﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Common.Utilities.Dispatcher;
using Common.Utilities;
using Workflows.Components.TextMining.Properties;

namespace Workflows.Components.TextMining.EnumerationObjects
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class TableDataExtractorComponent:WorkflowComponentBase
    {
        #region props
        private TableDataExtractorInstruction _Instruction;
        /// <summary>an object that encapsulate instruction settings.</summary>
        public override InstructionBase Instruction
        {
            get { return _Instruction; }
            set { _Instruction=(TableDataExtractorInstruction) value; }
        }

        private TableDataExtractorOutput _Output;
        /// <summary>an object to encapsulate output</summary>
        public override ResultBase Output
        {
            get { return _Output; }
            set { _Output=(TableDataExtractorOutput) value; }
        }

        /// <summary></summary>
        public int RunID
        {
            get
            {
                return _Instruction.RunID;
            }
            set
            {
                _Instruction.RunID = value;
            }
        }

        /// <summary></summary>
        public string FileListXmlFilePath
        {
            get
            {
                return this._Instruction.FileListXmlFilePath;
            }
            set
            {
                this._Instruction.FileListXmlFilePath = value;
            }
        }

        /// <summary></summary>
        public string TableScanXmlFilePath
        {
            get
            {
                return _Instruction.TableScanXmlFilePath;
            }
            set
            {
                _Instruction.TableScanXmlFilePath = value;
            }
        }

        /// <summary></summary>
        public string TableLayoutXmlFilePath
        {
            get
            {
                return this._Instruction.TableLayoutXmlFilePath;
            }
            set
            {
                this._Instruction.TableLayoutXmlFilePath = value;
            }
        }

        /// <summary></summary>
        public string TableExtractorOutputFolder
        {
            get
            {
                return this._Instruction.TableExtractorOutputFolder;
            }
            set
            {
                this._Instruction.TableExtractorOutputFolder = value;
            }
        }

        /// <summary></summary>
        public string LogFilePath
        {
            get
            {
                return this._Instruction.LogFilePath;
            }
            set
            {
                this._Instruction.LogFilePath = value;
            }
        }

        /// <summary></summary>
        public string ErrFilePath
        {
            get
            {
                return this._Instruction.ErrFilePath;
            }
            set
            {
                this._Instruction.ErrFilePath = value;
            }
        }

        /// <summary></summary>
        public int ThreadPoolSize
        {
            get
            {
                return this._Instruction.ThreadPoolSize;
            }
            set
            {
                this._Instruction.ThreadPoolSize = value;
            }
        }

        /// <summary></summary>
        public string ConnStr
        {
            get
            {
                return this._Instruction.ConnStr;
            }
            set
            {
                this._Instruction.ConnStr = value;
            }
        }

        /// <summary></summary>
        public string DocStatusOutputTable
        {
            get
            {
                return this._Instruction.DocStatusOutputTable;
            }
            set
            {
                this._Instruction.DocStatusOutputTable = value;
            }
        }

        /// <summary></summary>
        public string DocRecordOutputTable
        {
            get
            {
                return this._Instruction.DocRecordOutputTable;
            }
            set
            {
                this._Instruction.DocRecordOutputTable = value;
            }
        }

        /// <summary></summary>
        public string DocIDField
        {
            get
            {
                return this._Instruction.DocIDField;
            }
            set
            {
                this._Instruction.DocIDField = value;
            }
        }

        /// <summary></summary>
        public string RunIDField
        {
            get
            {
                return this._Instruction.RunIDField;
            }
            set
            {
                this._Instruction.RunIDField = value;
            }
        }

        /// <summary></summary>
        public string IsElectronicField
        {
            get
            {
                return this._Instruction.IsElectronicField;
            }
            set
            {
                this._Instruction.IsElectronicField = value;
            }
        }

        /// <summary></summary>
        public string IsScannedField
        {
            get
            {
                return this._Instruction.IsScannedField;
            }
            set
            {
                this._Instruction.IsScannedField = value;
            }
        }

        /// <summary></summary>
        public string PagesField
        {
            get
            {
                return this._Instruction.PagesField;
            }
            set
            {
                this._Instruction.PagesField = value;
            }
        }

        /// <summary></summary>
        public string RecordCountField
        {
            get
            {
                return this._Instruction.RecordCountField;
            }
            set
            {
                this._Instruction.RecordCountField = value;
            }
        }

        /// <summary></summary>
        public string DocFlagField
        {
            get
            {
                return this._Instruction.DocFlagField;
            }
            set
            {
                this._Instruction.DocFlagField = value;
            }
        }

        /// <summary></summary>
        public string CommentsField
        {
            get
            {
                return this._Instruction.CommentsField;
            }
            set
            {
                this._Instruction.CommentsField = value;
            }
        }

        /// <summary></summary>
        public Dictionary<string, string> SrcTgtFieldMappings
        {
            get
            {
                return this._Instruction.SrcTgtFieldMappings;
            }
            set
            {
                this._Instruction.SrcTgtFieldMappings = value;
            }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        public TableDataExtractorComponent()
            : base()
        {
            this.ComponentActivityType = WorkflowActivityType.SimpleActivity;
            this.ComponentCategory = WorkflowComponentCategory.Enumeration.ToString();
            this.ComponentName = "Table data extractor";
            this.Description = "Extract table data given table layout";
            this.ComponentIcon = Resources.adobe;
            this.ComponentImage = Resources.Form;

            this._Instruction =
                new TableDataExtractorInstruction(this.ComponentID, Guid.Empty,
                    1, string.Empty, string.Empty, string.Empty, string.Empty,
                    string.Empty, string.Empty, 10, string.Empty,
                    string.Empty, string.Empty, string.Empty, string.Empty,
                    string.Empty, string.Empty, string.Empty, string.Empty,
                    string.Empty, string.Empty, new Dictionary<string, string>());
            this._Output = new TableDataExtractorOutput(this.ComponentID, Guid.Empty,
                string.Empty, 0, 0);
        }

        /// <summary><para>subclass must implement this method to instantiate activity from xml</para></summary>
        public override WorkflowComponentBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                TableDataExtractorComponent component = base.Instantiate(xNode) as TableDataExtractorComponent;

                component.RunID = int.Parse(XmlDataUtil.GetAttributeValue(xNode, "RunID", "-1"));
                component.FileListXmlFilePath = XmlDataUtil.GetAttributeValue(xNode, "FileListXmlFilePath", "");
                component.TableScanXmlFilePath = XmlDataUtil.GetAttributeValue(xNode, "TableScanOutputXmlFilePath", "");
                component.TableLayoutXmlFilePath = XmlDataUtil.GetAttributeValue(xNode, "TableLayoutXmlFilePath", "");
                component.TableExtractorOutputFolder = XmlDataUtil.GetAttributeValue(xNode, "ResultFilePath", "");
                component.LogFilePath = XmlDataUtil.GetAttributeValue(xNode, "LogFilePath", "");
                component.ErrFilePath = XmlDataUtil.GetAttributeValue(xNode, "ErrFilePath", "");
                component.ThreadPoolSize = int.Parse(XmlDataUtil.GetAttributeValue(xNode, "ThreadPoolSize", "10"));

                component.ConnStr = XmlDataUtil.GetAttributeValue(xNode, "ConnectionString", "");
                component.DocStatusOutputTable = XmlDataUtil.GetAttributeValue(xNode, "StatusOutputTable", "");
                component.DocRecordOutputTable = XmlDataUtil.GetAttributeValue(xNode, "RecordOutputTable", "");
                component.DocIDField = XmlDataUtil.GetAttributeValue(xNode, "DocIDField", "");
                component.RunIDField = XmlDataUtil.GetAttributeValue(xNode, "RunIDField", "");
                component.IsElectronicField = XmlDataUtil.GetAttributeValue(xNode, "IsElectronicField", "");
                component.IsScannedField = XmlDataUtil.GetAttributeValue(xNode, "IsScannedField", "");
                component.PagesField = XmlDataUtil.GetAttributeValue(xNode, "PageField", "");
                component.RecordCountField = XmlDataUtil.GetAttributeValue(xNode, "RecordCountField", "");
                component.DocFlagField = XmlDataUtil.GetAttributeValue(xNode, "FlagField", "");
                component.CommentsField = XmlDataUtil.GetAttributeValue(xNode, "CommentField", "");

                XmlNodeList mappingNodes = xNode.SelectNodes("FieldMappings/FieldMapping");
                if (mappingNodes != null && mappingNodes.Count > 0)
                {
                    component.SrcTgtFieldMappings = new Dictionary<string, string>();
                    foreach (XmlNode mappingNode in mappingNodes)
                    {
                        string srcFieldName = XmlDataUtil.GetAttributeValue(mappingNode, "FieldNameInFile", "");
                        if (!component.SrcTgtFieldMappings.ContainsKey(srcFieldName))
                        {
                            string tgtFieldName = XmlDataUtil.GetAttributeValue(mappingNode, "FieldNameInTable", "");
                            component.SrcTgtFieldMappings.Add(srcFieldName, tgtFieldName);
                        }
                    }
                }
                return component;
            }
            else
            {
                throw new Exception("Unable to instantiate email: invalid type specified in xml node");
            }
        }

        /// <summary><para>must implementable method to serialize activity settings to xml</para></summary>
        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = base.Serialize(ref xDoc, ref parentNode);

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RunID", this.RunID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FileListXmlFilePath", this.FileListXmlFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TableScanOutputXmlFilePath", this.TableScanXmlFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TableLayoutXmlFilePath", this.TableLayoutXmlFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ResultFilePath", this.TableExtractorOutputFolder);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "LogFilePath", this.LogFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ErrFilePath", this.ErrFilePath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ThreadPoolSize", this.ThreadPoolSize.ToString());

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ConnectionString", this.ConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StatusOutputTable", this.DocStatusOutputTable);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RecordOutputTable", this.DocRecordOutputTable);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "DocIDField", this.DocIDField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RunIDField", this.RunIDField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "IsElectronicField", this.IsElectronicField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "IsScannedField", this.IsScannedField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "PageField", this.PagesField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RecordCountField", this.RecordCountField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FlagField", this.DocFlagField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "CommentField", this.CommentsField);

            if (this.SrcTgtFieldMappings != null && this.SrcTgtFieldMappings.Count > 0)
            {
                XmlNode mappingRootNode = XmlDataUtil.AddElement(ref xDoc, xNode, "FieldMappings");
                foreach (string srcField in this.SrcTgtFieldMappings.Keys)
                {
                    string tgtFieldName = this.SrcTgtFieldMappings[srcField];
                    XmlNode mappingNode = XmlDataUtil.AddElement(ref xDoc, mappingRootNode, "FieldMapping");
                    XmlDataUtil.UpdateAttribute(ref xDoc, mappingNode, "FieldNameInFile", srcField);
                    XmlDataUtil.UpdateAttribute(ref xDoc, mappingNode, "FieldNameInTable", tgtFieldName);
                }
            }

            return xNode;
        }
    }
}
